%%%-------------------------------------------------------------------
%%% @author GAME4
%%% @copyright (C) 2018, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 14. 五月 2018 17:31
%%%-------------------------------------------------------------------
-module(hprose_conn).
-author("GAME4").

-behaviour(gen_server).

%% API
-export([start_link/4]).

%% gen_server callbacks
-export([init/1,
  handle_call/3,
  handle_cast/2,
  handle_info/2,
  terminate/2,
  code_change/3]).

-define(SERVER, ?MODULE).

%% 空闲状态的生命期.
-define(IDLE_LIFE_TIME, 600).

%% 释放socket，检测攻击
-define(RELEASE_PASSIVE_TIMEOUT, 30).

-record(state, {
  socket :: inet:socket()
}).

%%%===================================================================
%%% API
%%%===================================================================

start_link(ListenerPid, Socket, Transport, Opts) ->
  proc_lib:start_link(?MODULE, init, [[ListenerPid, Socket, Transport, Opts]]).

%%%===================================================================
%%% gen_server callbacks
%%%===================================================================

init([ListenerPid, Socket, Transport, _Opts]) ->
  ok = proc_lib:init_ack({ok, self()}),
  ok = ranch:accept_ack(ListenerPid),
  ok = Transport:setopts(Socket, [{active, 300}, {packet, 2}, {packet_size, 16384}, {keepalive, true}, {reuseaddr, true}]),
  erlang:send_after(?RELEASE_PASSIVE_TIMEOUT * 1000, self(), release_passive),
  gen_server:enter_loop(?MODULE, [], #state{socket = Socket});
init([]) ->
  {ok, undefined}.

handle_call(_Request, _From, State) ->
  {reply, ok, State}.

handle_cast(_Request, State) ->
  {noreply, State}.

handle_info({tcp, Socket, _RawData}, #state{socket = Socket} = State) ->
  %% tcp 消息处理.
  {noreply, State};

%% 每个一定时间重置Socket
handle_info(release_passive, #state{socket = Socket} = State) ->
  erlang:send_after(?RELEASE_PASSIVE_TIMEOUT * 1000, self(), release_passive),
  inet:setopts(Socket, [{active, 300}]),
  {noreply, State};

%% 触发这个就要检查一下 是否有消息攻击
handle_info({tcp_passive, _Socket}, State) ->
  {stop, normal, State};

handle_info({tcp_error, _Socket, _Reason}, State) ->
  {stop, normal, State};

handle_info({tcp_closed, _Socket}, State) ->
  {stop, normal, State};

handle_info({'DOWN', _MRef, process, _Pid, _Info}, State) ->
  {stop, normal, State};

handle_info(_Info, State) ->
  {noreply, State}.

terminate(_Reason, _State) ->
  ok.

code_change(_OldVsn, State, _Extra) ->
  {ok, State}.

%%%===================================================================
%%% Internal functions
%%%===================================================================
